/**
 ******************************************************************************
 * @file    tx_initialize_low_level.c
 * @author  Iron
 * @date    2020-01-01
 * @version v1.0
 * @brief   tx_initialize_low_level c file
 */

/* Private includes ----------------------------------------------------------*/
#include <stdint.h>
#include "stm32f0xx_hal.h"
#include "tx_api.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern VOID *_tx_initialize_unused_memory;
extern VOID *_tx_thread_system_stack_ptr;

/* Private function ----------------------------------------------------------*/
VOID _tx_thread_context_save(VOID);
VOID _tx_thread_context_restore(VOID);
VOID _tx_timer_interrupt(VOID);
void Error_Handler(void);

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
    _tx_execution_isr_enter()                // @ Call the ISR enter function
#endif
    _tx_timer_interrupt();
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
    _tx_execution_isr_exit()             //     @ Call the ISR exit function
#endif
}

/*!< STM32F0xx uses 2 Bits for the Priority Levels */
void _tx_pendsv_init(uint32_t PendSV_Priority)
{
    if (PendSV_Priority < (1UL << __NVIC_PRIO_BITS))
    {
        HAL_NVIC_SetPriority(PendSV_IRQn, PendSV_Priority, 0);
        HAL_NVIC_EnableIRQ(PendSV_IRQn);
    }
    else
    {
        /* NVIC Priority Config Error*/
        Error_Handler();
    }
}

void _tx_systick_init(uint32_t uwTickFreq, uint32_t SysTick_Priority)
{
    if (HAL_SYSTICK_Config(SystemCoreClock / uwTickFreq) == 0U)
    {
        /* Configure the SysTick IRQ priority */
        if (SysTick_Priority < (1UL << __NVIC_PRIO_BITS))
        {
            HAL_NVIC_SetPriority(SysTick_IRQn, SysTick_Priority, 0U);
            HAL_NVIC_EnableIRQ(SysTick_IRQn);
        }
        else
        {
            /* NVIC Priority Config Error*/
            Error_Handler();
        }
    }
}

void _tx_initialize_low_level(void)
{
    TX_INTERRUPT_SAVE_AREA
    TX_DISABLE

    _tx_initialize_unused_memory = (uint8_t *)(_TX_FIRST_UNUSED_MEMORY) + 4;
    _tx_thread_system_stack_ptr = (uint8_t *)(_TX_INITIAL_SP);

    _tx_systick_init(TX_TIMER_TICKS_PER_SECOND, 1);
    _tx_pendsv_init(3);

    TX_RESTORE
}

/**
 * @}
 */

/******************* (C)COPYRIGHT 2020 ***** END OF FILE *********************/
